// C/C++ Standard Librarys
#ifndef MY_HEADER_H
#define MY_HEADER_H

// Header file contents


#include <iostream>     // 输入输出流
#include <vector>      // 向量容器
#include <algorithm>   // 算法库
#include <chrono>      // 时间相关功能
#include <iomanip>     // 输入输出格式控制

// Thrid Party Librarys
#include <opencv2/opencv.hpp>      // OpenCV主要头文件
#include <opencv2/dnn/dnn.hpp>     // OpenCV深度学习模块

// RDK BPU libDNN API
#include "dnn/hb_dnn.h"           // BPU基础功能
#include "dnn/hb_dnn_ext.h"       // BPU扩展功能
#include "dnn/plugin/hb_dnn_layer.h"    // BPU层定义
#include "dnn/plugin/hb_dnn_plugin.h"   // BPU插件
#include "dnn/hb_sys.h"           // BPU系统功能

#include "utils.h"
// 错误检查宏
#define RDK_CHECK_SUCCESS(value, errmsg)                        \
    do                                                          \
    {                                                           \
        auto ret_code = value;                                  \
        if (ret_code != 0)                                      \
        {                                                       \
            std::cout << errmsg << ", error code:" << ret_code; \
            return ret_code;                                    \
        }                                                       \
    } while (0);
    


struct SegRes {
    std::string time_stamp;
    int detect_num;
    std::vector<int> classes_ids;
    std::vector<float> scores;
    std::vector<cv::Rect2d> bboxes;
    std::vector<cv::Mat> maskes;

    void clear() {
        time_stamp = "";          // 清空时间戳
        detect_num = 0;
        classes_ids.clear();      // 清空类别 ID
        scores.clear();           // 清空置信度分数
        bboxes.clear();           // 清空边界框
        maskes.clear();           // 清空分割掩码
    }
};


class BPU_Detect 
{
    public:
    	BPU_Detect(const std::string& model_path = "",
                 int classes_num = 80,
                 float nms_threshold = 0.45f,
                 float score_threshold = 0.25f,
                 int nms_top_k = 300);

        ~BPU_Detect();    

        bool Init(); 
        bool Infer(const cv::Mat img); 
        SegRes ObtainRes(){ return seg_res_;};
        bool Release();  
        cv::Mat DrawResults(){ return concatenated_result_;};


    private:
    	bool LoadModel();  // 加载模型
        int GetModelInfo();  // 获取模型信息
        void MallocMemeory();
        bool PreProcess(const cv::Mat& input_img, int type = 0);  // 图像预处理
        void PostProcess();  // 后处理
        // void DrawResults(cv::Mat& img);  // 绘制结果
        // void PrintResults() const;  // 打印检测结果
   
    
    private:
        hbPackedDNNHandle_t packed_dnn_handle_;
        hbDNNHandle_t dnn_handle_;
        hbDNNTensor input_;
        hbDNNTensorProperties input_properties_;
        hbDNNTensor *output_ = nullptr;
        hbDNNTaskHandle_t task_handle_ = nullptr;


		// 成员变量（按照构造函数初始化顺序排列）
        std::string model_path_;      // 模型文件路径
        int classes_num_;             // 类别数量
        float nms_threshold_;         // NMS阈值
        float score_threshold_;       // 置信度阈值
        int nms_top_k_;               // NMS保留的最大框数
        // pre_process
        // cv::Mat img_nv12_;
        cv::Mat resize_img_;
        // post_process 
    private:
        int32_t input_H_ = 640;
        int32_t input_W_ = 640;
        int32_t reg_ = 16;
        int32_t mces_ = 32;
        int32_t order_we_want[10][3];
        int32_t H_4, H_8, H_16, H_32;
        int32_t W_4, W_8, W_16, W_32;
        int order_[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        int32_t output_count_ = 10;


    private:
        // visual
        cv::Mat final_result_;
        cv::Mat concatenated_result_;
        SegRes seg_res_;

        
};

#endif // MY_HEADER_H
